package com.mxpio.erp.plan.mrp.policy.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.mxpio.erp.common.quality.entity.MoInQualityOrder;
import com.mxpio.erp.common.quality.entity.MoInQualityOrderLine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.mxpio.erp.common.enums.OrderEnums.AccessType;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.order.service.OrderLineService;
import com.mxpio.erp.common.order.service.OrderService;
import com.mxpio.erp.common.vo.NoticeClassVo;
import com.mxpio.erp.common.workshop.entity.DefectiveProductsNotice;
import com.mxpio.erp.common.workshop.entity.DefectiveProductsNoticeLine;
import com.mxpio.erp.common.workshop.entity.ManufactureOrder;
import com.mxpio.erp.common.workshop.entity.ManufactureOrderItem;
import com.mxpio.erp.common.workshop.entity.MoInNotice;
import com.mxpio.erp.common.workshop.entity.MoInNoticeLine;
import com.mxpio.erp.common.workshop.entity.MoPickingNotice;
import com.mxpio.erp.common.workshop.entity.MoPickingNoticeLine;
import com.mxpio.erp.plan.mrp.Context;
import com.mxpio.erp.plan.mrp.CountModelMap;
import com.mxpio.erp.plan.mrp.bo.CountModel;
import com.mxpio.erp.plan.mrp.policy.LrpOrderPolicy;
import com.mxpioframework.jpa.JpaUtil;

/**
 * 计算生产订单剩余数量
 * @author maxp
 *
 */
@Component
public class OrderPolicy extends LrpOrderPolicy {
	
	@Autowired
    private OrderService orderService;
	
	@Autowired
    private OrderLineService orderLineService;

	// 计算生产订单 未完成的数量汇总，通过context.setOrderCount(orderCount)方法返回。
	@Override
	public void apply(Context context) {
		
		CountModelMap<List<CountModel>> result = new CountModelMap<List<CountModel>>();
		
		List<ManufactureOrder> mos = JpaUtil.linq(ManufactureOrder.class)
				.equal("closeStatus", OrderStatusEnums.CloseStatus.OPEN.getStatusCode())
				.notEqual("orderStatus", OrderStatusEnums.OrderStatus.CLEARED.getStatusCode())
				.list();
		List<NoticeClassVo> noticeClassVos = new ArrayList<>();
		noticeClassVos.add(new NoticeClassVo(MoInNotice.class, MoInNoticeLine.class));
		noticeClassVos.add(new NoticeClassVo(MoInQualityOrder.class, MoInQualityOrderLine.class));//考虑生成生产入库检验单的情况
		orderService.handleBizOrderQuantity(mos, noticeClassVos, AccessType.IN.getCode());
		for(ManufactureOrder mo : mos){
			try {
				CountModel countModel = new CountModel();
				BigDecimal count = new BigDecimal(0);
				count = count.add(mo.getOrderQuantity().subtract(mo.getActualQuantity()));
				countModel.setCount(count);
				countModel.setItemCode(mo.getProductItemCode());
				countModel.setOrderDate(mo.getEndDate());
				countModel.setType(2);
				countModel.setBoCode(mo.getBizNo());
				countModel.setOrderStartDate(mo.getStartDate());
				countModel.setRemark(mo.getMemo());
				
				indexProcessAdd(context, mo, result, countModel);
				
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
		
		// 委外任务未转化成订单的在制物料数量
		/*List<OutsourceTask> outsourceTaskList = JpaUtil.linq(OutsourceTask.class).lessThan("scheduleStatus", ScheduleStatus.COMPLETED.getValue()).list();
		if(outsourceTaskList != null && !outsourceTaskList.isEmpty()) {
			for(OutsourceTask p : outsourceTaskList) {
				try {
					CountModel countModel = new CountModel();
					BigDecimal count = new BigDecimal(0);
					// 已生成订单数量
					BigDecimal orderGenerated = p.getOrderGenerated();
					if(orderGenerated == null) {
						orderGenerated = new BigDecimal(0);
					}
					count = count.add(p.getProductNumber().subtract(orderGenerated));
					countModel.setCount(count);
					countModel.setItemCode(p.getItemCode());
					countModel.setOrderDate(p.getPlanEndDate());
					countModel.setType(2);
					countModel.setBoCode(p.getProductionPlanCode());
					countModel.setOrderStartDate(p.getPlanStartDate());
					countModel.setRemark(p.getProductionPlanCode());
					
					indexProcessAdd(context, p, result, countModel);
				}catch (Exception e) {
					e.printStackTrace();
					continue;
				}
			}
		}*/
		// 订单在制物料数量
		/*List<ManufactureOrderItem> productPlanMaterielList = JpaUtil.linq(ManufactureOrderItem.class)
				.exists(ManufactureOrder.class)
					.equal("closeStatus", OrderStatusEnums.CloseStatus.OPEN.getStatusCode())
					.notEqual("orderStatus", OrderStatusEnums.OrderStatus.CLEARED.getStatusCode())
				.end()
				.list();
		Map<String, ManufactureOrder> map = JpaUtil.index(mos);
        List<NoticeClassVo> lienNoticeClassVos = new ArrayList<>();
        lienNoticeClassVos.add(new NoticeClassVo(MoPickingNotice.class, MoPickingNoticeLine.class));//领/补/退
        lienNoticeClassVos.add(new NoticeClassVo(DefectiveProductsNotice.class, DefectiveProductsNoticeLine.class));//不良品退料
		orderLineService.handleBizOrderLineQuantity(productPlanMaterielList, lienNoticeClassVos, AccessType.OUT.getCode());
		if(productPlanMaterielList != null && !productPlanMaterielList.isEmpty()) {
			for(ManufactureOrderItem p : productPlanMaterielList) {
				try {
					CountModel countModel = new CountModel();
					BigDecimal count = new BigDecimal(0);
					// 已入库数量
					BigDecimal storageNum = p.getActualQuantity().subtract(p.getActualRejectQuantity());
					if(storageNum == null) {
						storageNum = new BigDecimal(0);
					}
					count = count.add(p.getQuantity().subtract(storageNum));
					countModel.setCount(count);
					countModel.setItemCode(p.getItemCode());
					countModel.setOrderDate(map.get(p.getBizNo())==null?null:map.get(p.getBizNo()).getOrderDate());
					countModel.setType(1);
					countModel.setBoCode(p.getBizNo());
					countModel.setOrderStartDate(map.get(p.getBizNo())==null?null:map.get(p.getBizNo()).getStartDate());
					
					indexProcessAdd(context, p, result, countModel);
				}catch (Exception e) {
					e.printStackTrace();
					continue;
				}
				
			}
		}*/
		
		List<ManufactureOrderItem> productPlanMaterielList = JpaUtil.linq(ManufactureOrderItem.class)
				.exists(ManufactureOrder.class)
					.equalProperty("bizNo", "bizNo")
					.equal("closeStatus", OrderStatusEnums.CloseStatus.OPEN.getStatusCode())
					.notEqual("orderStatus", OrderStatusEnums.OrderStatus.CLEARED.getStatusCode())
				.end()
				.list();
        List<NoticeClassVo> lienNoticeClassVos = new ArrayList<>();
        lienNoticeClassVos.add(new NoticeClassVo(MoPickingNotice.class, MoPickingNoticeLine.class));//领/补/退
        lienNoticeClassVos.add(new NoticeClassVo(DefectiveProductsNotice.class, DefectiveProductsNoticeLine.class));//不良品退料
		orderLineService.handleBizOrderLineQuantity(productPlanMaterielList, lienNoticeClassVos, AccessType.OUT.getCode());
		
		Map<String, List<ManufactureOrderItem>> map = JpaUtil.classify(productPlanMaterielList, "bizNo");
		context.setOrderLines(map);
		context.setOrderCount(result);
	}

	
}
